package QC.MessageBox.beans.wxmsg;

import QC.MessageBox.common.Constants;
import QC.MessageBox.common.EmojiUtil;
import QC.MessageBox.common.XMLUtils;
import QC.MessageBox.wxmpase.AesException;
import QC.MessageBox.wxmpase.WXBizMsgCrypt;
import io.vertx.core.http.HttpServerRequest;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * Created by Andaren on 2017/4/27.
 * Used for: 加密的微信消息
 */
public class WXEncryptMsg {

    private String toUserName;  // 开发者微信号(原始账号)
    private String encrypt;     // 加密之后的消息

    private String decrypt;     // 解密之后的消息

    private String msg_signature;// 消息签名
    private String encrypt_type; // 消息加密类型
    private String timestamp;    // 时间戳
    private String nonce;        // 随机字符串

    private String srcXmlStr;    // xml源数据
    private Map<String, Object> elementMap; // xml元素键值对
    private Boolean isEncrypted; // 该消息是否加密

    public WXEncryptMsg (String xmls, HttpServerRequest request) {
        this.srcXmlStr = xmls;
        this.encrypt = xmls;

        if (request != null) {
            this.msg_signature = request.getParam("msg_signature");
            this.timestamp = request.getParam("timestamp");
            this.nonce = request.getParam("nonce");
            this.encrypt_type = request.getParam("encrypt_type");
        }
    }

    public WXEncryptMsg init() {

        try {
            this.elementMap = XMLUtils.xmlStrToMap(srcXmlStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 初始化开发者ID（公众号原始ID）
        this.toUserName = String.valueOf(elementMap.get("ToUserName"));
        // 是否加密
        isEncrypted = (null != elementMap.get("Encrypt"));
        return this;
    }

    public String getToUserName() {
        return toUserName;
    }

    public WXEncryptMsg setToUserName(String toUserName) {
        this.toUserName = toUserName;
        return this;
    }

    public String getEncrypt() {
        return encrypt;
    }

    public WXEncryptMsg setEncrypt(String encrypt) {
        this.encrypt = encrypt;
        return this;
    }

    public String getMsg_signature() {
        return msg_signature;
    }

    public WXEncryptMsg setMsg_signature(String msg_signature) {
        this.msg_signature = msg_signature;
        return this;
    }

    public String getEncrypt_type() {
        return encrypt_type;
    }

    public WXEncryptMsg setEncrypt_type(String encrypt_type) {
        this.encrypt_type = encrypt_type;
        return this;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public WXEncryptMsg setTimestamp(String timestamp) {
        this.timestamp = timestamp;
        return this;
    }

    public String getNonce() {
        return nonce;
    }

    public WXEncryptMsg setNonce(String nonce) {
        this.nonce = nonce;
        return this;
    }

    public String getDecrypt() {
        return decrypt;
    }

    public WXEncryptMsg setDecrypt(String decrypt) {
        this.decrypt = decrypt;
        return this;
    }

    public String getSrcXmlStr() {
        return srcXmlStr;
    }

    public WXEncryptMsg setSrcXmlStr(String srcXmlStr) {
        this.srcXmlStr = srcXmlStr;
        return this;
    }

    public Map<String, Object> getElementMap() {
        return elementMap;
    }

    public WXEncryptMsg setElementMap(Map<String, Object> elementMap) {
        this.elementMap = elementMap;
        return this;
    }

    public Boolean getEncrypted() {
        return isEncrypted;
    }

    public WXEncryptMsg setEncrypted(Boolean encrypted) {
        isEncrypted = encrypted;
        return this;
    }

    /**
     * 处理消息中的表情
     */
    public WXEncryptMsg filterWXMsg() {
        this.decrypt = EmojiUtil.filterEmoji(decrypt);
        return this;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("WXEncryptMsg{");
        sb.append("toUserName='").append(toUserName).append('\'');
        sb.append(", encrypt='").append(encrypt).append('\'');
        sb.append(", decrypt='").append(decrypt).append('\'');
        sb.append(", msg_signature='").append(msg_signature).append('\'');
        sb.append(", encrypt_type='").append(encrypt_type).append('\'');
        sb.append(", timestamp='").append(timestamp).append('\'');
        sb.append(", nonce='").append(nonce).append('\'');
        sb.append(", srcXmlStr='").append(srcXmlStr).append('\'');
        sb.append(", elementMap=").append(elementMap);
        sb.append(", isEncrypted=").append(isEncrypted);
        sb.append('}');
        return sb.toString();
    }

    /**
     * 解密消息
     * @param appId
     * @return
     */
    public WXEncryptMsg decryptWXMsg(String appId) {
        if (StringUtils.isNotBlank(encrypt_type)) {
            try {
                WXBizMsgCrypt pc = new WXBizMsgCrypt(Constants.TOKEN, Constants.ENCODINGAESKEY, appId);
                decrypt = pc.decryptMsg(msg_signature, timestamp, nonce, encrypt);
            } catch (AesException aes) {
                aes.printStackTrace();
            }
        }
        return this;
    }

    /**
     * 重新设置xml-elements-Map
     * @return
     */
    public WXEncryptMsg reSetElementMap() {
        try {
            this.elementMap = XMLUtils.xmlStrToMap(decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }
}
